home *** CD-ROM | disk | FTP | other *** search
/ Gekkan Dennou Club 147 / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan).7z / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan) (Track 1).bin / docs / ippon / eshot / 5 / eshot.c next >
C/C++ Source or Header  |  2000-07-07  |  6KB  |  231 lines

  1. /* eshot.c */
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <math.h>        /* sin,cos を使うために */
  6. #include <sys/iocs.h>
  7. #include "XSP2lib.H"
  8.  
  9. #define PCG_MAX    32        /* パターンデータの個数 */
  10.  
  11. static char pcg_alt[PCG_MAX + 1];    /* PCG配置管理テーブル */
  12. static char pcg_dat[PCG_MAX * 128];    /* PCGデータファイル読み込みバッファ */
  13.  
  14. static unsigned short pal_dat[16][15];    /* パレットデータ */
  15.  
  16.  
  17. #define ESHOT_MAX    200    /* 敵弾最大数 */
  18. #define ESHOT_SPEED    0.75    /* 敵弾の速度 */
  19.  
  20.  
  21. /* 敵弾構造体 */
  22. typedef struct _eshot {
  23.     signed short x;        /* 敵弾のX座標 */
  24.     signed short y;        /*  〃 Y座標 */
  25.     unsigned char type;    /*  〃 種類(=0 なら未使用) */
  26.     signed int lx, ly;    /* 32bit X,Y 座標 ( l = longword ) */
  27.     signed int vx, vy;    /* 32bit X,Y 速度 ( v = velocity ) */
  28.     struct _eshot *next;    /* 次の構造体へのポインタ */
  29. } ESHOT;
  30.  
  31. ESHOT *eshot_top;        /* 使用中のワークのリスト */
  32. int eshot_count;        /* 敵弾の数 */
  33.  
  34.  
  35.  
  36. typedef struct {
  37.     signed int x, y;
  38. } VECTOR;
  39.  
  40. VECTOR xytable[256];        /* sin,cos テーブル */
  41.  
  42.  
  43.  
  44. /* ゲーム開始時に呼ばれる */
  45. void EshotInit (void)
  46. {
  47.     eshot_count = 0;    /* 敵弾数は0 */
  48. }
  49.  
  50.  
  51.  
  52. /* 敵弾出現時に呼ばれる */
  53. /* 引き数 : 種類, X座標, Y座標, 角度 */
  54. void EshotAlloc (unsigned char type, signed short x, signed short y, unsigned char angle)
  55. {
  56.     ESHOT *p;
  57.  
  58.     if (eshot_count >= ESHOT_MAX)    /* 敵弾数が ESHOT_MAX を越えているか? */
  59.         return;        /* これ以上は出さない */
  60.     eshot_count++;
  61.  
  62.     p = malloc (sizeof (ESHOT));    /* ノードを1個確保 */
  63.     if (p == NULL)        /* 確保できたか? */
  64.         return;        /* 確保できなかった(メモリ不足) */
  65.  
  66.     /* リスト構造で管理 */
  67.     if (eshot_top == NULL) {
  68.         /* 1個も弾が出ていない場合 */
  69.         p->next = NULL;    /* 次はない */
  70.     } else {
  71.         p->next = eshot_top;    /* 「今までの先頭」を「今確保したノード」の次にする */
  72.     }
  73.     eshot_top = p;        /* 今確保したノードを先頭にする */
  74.  
  75.     p->lx = (x - 8) * 65536;    /* (8,8) がスプライト座標の中心なので補正 */
  76.     p->ly = (y - 8) * 65536;
  77.     p->vx = xytable[angle].x;
  78.     p->vy = xytable[angle].y;
  79.     p->type = type;
  80. }
  81.  
  82.  
  83.  
  84. /* 垂直同期ごとに呼ばれる */
  85. void EshotMove (void)
  86. {
  87.     ESHOT *p, *q;
  88.  
  89.     p = eshot_top;        /* 現在注目しているワーク */
  90.     q = NULL;        /* 1つ前のワーク(ワーク削除時に必要) */
  91.  
  92.     while (p != NULL) {
  93.         p->lx += p->vx;    /* vx だけ移動 */
  94.         p->ly += p->vy;    /* vy だけ移動 */
  95.  
  96.         p->x = p->lx / 65536;    /* lx の整数部を取り出して x に */
  97.         p->y = p->ly / 65536;    /* ly の整数部を取り出して y に */
  98.  
  99.         /* 敵弾が画面外に出たか? */
  100.         if ((p->x < 0) || (p->x > 256 + 16) || (p->y < 0) || (p->y > 256 + 16)) {
  101.             /* 画面外に出たので消去 */
  102.             eshot_count--;
  103.  
  104.             if (q == NULL) {    /* リストの一番最初を削除 */
  105.                 eshot_top = p->next;
  106.                 free (p);    /* メモリを開放 */
  107.                 q = NULL;
  108.                 p = eshot_top;
  109.             } else {
  110.                 q->next = p->next;
  111.                 free (p);    /* メモリを開放 */
  112.                 p = q->next;
  113.             }
  114.         } else {
  115.             xsp_set (p->x, p->y, p->type, 0x033f);
  116.  
  117.             q = p;
  118.             p = p->next;
  119.         }
  120.     }
  121. }
  122.  
  123.  
  124.  
  125. int main (int argc, char *argv[])
  126. {
  127.     FILE *fp;
  128.     int i, j;
  129.     int game_over = 0;
  130.     unsigned char angle = 0;    /* 次に撃つ弾の角度 */
  131.     unsigned char type = 1;    /* 次に撃つ弾の種類 */
  132.     int sprites;        /* スプライトの枚数 */
  133.  
  134.     if (argc != 1) {
  135.         printf (
  136.                    "敵弾テストその5 ESHOT.X\n"
  137.                    "        programmed by Mitsuky <FreeSoftware>\n"
  138.                    "弾のワークをリスト構造で管理するようにした\n"
  139.                    "&弾がちゃんと画面の中央から出るようにした\n"
  140.             );
  141.         exit (-1);
  142.     }
  143.     printf ("データテーブルを作成します。\n");
  144.     for (i = 0; i < 256; i++) {
  145.         xytable[i].x = (signed int) (cos (2.0 * M_PI * (long) i / 256.0) * 65536.0 * ESHOT_SPEED);
  146.         xytable[i].y = (signed int) (sin (2.0 * M_PI * (long) i / 256.0) * 65536.0 * ESHOT_SPEED);
  147.     }
  148.  
  149.  
  150.     _iocs_crtmod (10);    /* 256x256ドット グラフィック画面 256色 2画面 */
  151.     _iocs_g_clr_on ();    /* グラフィック画面の初期化 */
  152.     _iocs_sp_init ();    /* スプライトの初期化 */
  153.     _iocs_sp_on ();
  154.  
  155.     /* pcg_dat にパターンデータを読み込む */
  156.     fp = fopen ("ESHOT.SP", "rb");
  157.     fread (pcg_dat, sizeof (char), PCG_MAX * 128, fp);
  158.     fclose (fp);
  159.  
  160.     /* pal_buf に一旦パレットデータを読み込む */
  161.     fp = fopen ("ESHOT.PAL", "rb");
  162.     fread (pal_dat, sizeof (unsigned short), 16 * 15, fp);
  163.     fclose (fp);
  164.     /* パレットデータを定義 */
  165.     /* (1パレットブロック=16色) × (15ブロックぶん) 定義する */
  166.     {
  167.         unsigned short *p = (unsigned short *) pal_dat;
  168.         for (i = 1; i < 15; i++)
  169.             for (j = 0; j < 16; j++)
  170.                 _iocs_spalet (0x80000000 | j, i, *p++);
  171.     }
  172.  
  173.     xsp_on ();
  174.     xsp_mode (3);
  175.     /* パターンデータを定義 */
  176.     xsp_pcgdat_set (pcg_dat, pcg_alt, sizeof (pcg_alt));
  177.  
  178.     /* グラフィック画面に線を引く */
  179.     {
  180.         struct _lineptr lp;
  181.         lp.x1 = 0;
  182.         lp.y1 = 128;
  183.         lp.x2 = 255;
  184.         lp.y2 = 128;
  185.         lp.color = 15;
  186.         lp.linestyle = 0xaaaa;
  187.         _iocs_line (&lp);
  188.         lp.x1 = 128;
  189.         lp.y1 = 0;
  190.         lp.x2 = 128;
  191.         lp.y2 = 255;
  192.         _iocs_line (&lp);
  193.     }
  194.  
  195.     printf ("ジョイスティックの\n"
  196.         " [B] ボタンを押すと弾を撃ちます\n"
  197.         " [A] ボタンを押すと終了します\n");
  198.  
  199.  
  200.     EshotInit ();
  201.  
  202.     do {
  203.         xsp_vsync (0);    /* 垂直同期待ち */
  204.         j = _iocs_joyget (0);    /* ジョイスティック0番 */
  205.  
  206.         /* [A] ボタンが押されたか? */
  207.         if ((j & 0b00100000) == 0)
  208.             game_over = !0;        /* ゲームオーバーに */
  209.  
  210.         /* [B] ボタンが押されたか? */
  211.         if ((j & 0b1000000) == 0) {
  212.             EshotAlloc (type, 144, 144, angle);    /* 種類 type の敵弾を座標(144,144)、角度 angle で発生 */
  213.             angle += 8;    /* 角度を進める */
  214.             type++;    /* 種類を進める(意味無し) */
  215.             if (type > 5)
  216.                 type = 1;
  217.         }
  218.         EshotMove ();
  219.         sprites = xsp_out ();    /* 表示 */
  220.  
  221.         printf ("弾数 = %3d  \n\x0b", sprites);
  222.         /* 0x0b はカーソルを1行上に移動する */
  223.         /* Human68K ユーザーズマニュアルの付録 ASCII 制御コードの欄参照 */
  224.     } while (!game_over);
  225.  
  226.     xsp_off ();
  227.  
  228.     _iocs_crtmod (16);
  229.     return (0);
  230. }
  231.